#  -*- coding:utf-8 -*- 
"""
@ author: 罗金盛
@ time: 2023/11/16 
@ file: numpy计算信息熵、交叉熵.py

"""
import numpy as np

# 定义真实概率分布和预测概率分布
Y = np.array([1, 0, 0])
y1 = np.array([0, 1, 0])
y2 = np.array([0.8, 0.1, 0.1])

# 添加一个很小的值以防止log(0)的出现。当计算信息熵和交叉熵时，出现了警告信息，这是因为在计算对数时遇到了零值或负值，导致结果为无定义或无穷大。在熵和交叉熵计算中，这通常发生在概率值没有正确归一化的情况下。
epsilon = 1e-15

# 计算信息熵
def entropy(y):
    y = np.clip(y, epsilon, 1 - epsilon)  # 避免概率为0或1时的问题
    return -np.sum(y * np.log2(y))

entropy_Y = entropy(Y)
entropy_y1 = entropy(y1)
entropy_y2 = entropy(y2)

print(f"信息熵 H(Y): {entropy_Y}")
print(f"信息熵 H(y1): {entropy_y1}")
print(f"信息熵 H(y2): {entropy_y2}")

# 计算交叉熵
def cross_entropy(Y, y_pred):
    y_pred = np.clip(y_pred, epsilon, 1 - epsilon)  # 避免概率为0或1时的问题
    return -np.sum(Y * np.log2(y_pred))

cross_entropy_y1 = cross_entropy(Y, y1)
cross_entropy_y2 = cross_entropy(Y, y2)

print(f"交叉熵 H(Y, y1): {cross_entropy_y1}")
print(f"交叉熵 H(Y, y2): {cross_entropy_y2}")
